package com.example.elysiumease;

import com.example.elysiumease.mapper.SoulMapper;
import com.example.elysiumease.model.Soul;
import com.example.elysiumease.model.Soul.Gender;
import com.example.elysiumease.model.Soul.SoulStatus;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Commit;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@Transactional
@Commit
public class SoulMapperTest {

    @Autowired
    private SoulMapper soulMapper;

    // 测试灵魂基础数据
    private Soul createTestSoul() {
        return new Soul() {{
            setIdCardHash(UUID.randomUUID().toString().replace("-", ""));
            setFullName("Test Soul");
            setGender(Gender.M);
            setBirthDate(LocalDate.of(1990, 1, 1));
            setDeathDate(LocalDate.of(2023, 12, 1));
            setDeathCause("System Test");
            setLifeSummary("Test life summary");
            setInitialScore(new BigDecimal("85.50"));
            setCurrentStatus(SoulStatus.PENDING);
        }};
    }

    @Test
    void testInsertSoul() {
        Soul soul = createTestSoul();

        // 测试插入操作
        int result = soulMapper.insert(soul);
        assertEquals(1, result);
        assertNotNull(soul.getSoulId(), "插入后应生成灵魂ID");

        // 验证数据完整性
        Soul dbSoul = soulMapper.selectById(soul.getSoulId());
        assertNotNull(dbSoul, "应能查询到新插入的灵魂记录");
        assertEquals(soul.getIdCardHash(), dbSoul.getIdCardHash(), "身份证哈希应一致");
        assertEquals(soul.getInitialScore().setScale(2), dbSoul.getInitialScore(), "初始分数精度验证");
    }

    @Test
    void testUpdateSoulStatus() {
        // 插入初始数据
        Soul soul = createTestSoul();
        soulMapper.insert(soul);

        // 修改状态和分数
        soul.setCurrentStatus(SoulStatus.JUDGING);
        soul.setInitialScore(new BigDecimal("90.00"));

        int updateResult = soulMapper.update(soul);
        assertEquals(1, updateResult, "应成功更新1条记录");

        // 验证更新结果
        Soul updatedSoul = soulMapper.selectById(soul.getSoulId());
        assertAll("更新字段验证",
                () -> assertEquals(SoulStatus.JUDGING, updatedSoul.getCurrentStatus()),
                () -> assertEquals(0, new BigDecimal("90.00").compareTo(updatedSoul.getInitialScore()))
        );
    }

    @Test
    void testDeleteSoul() {
        // 准备测试数据
        Soul soul = createTestSoul();
        soulMapper.insert(soul);

        // 执行删除
        int deleteResult = soulMapper.deleteById(soul.getSoulId());
        assertEquals(1, deleteResult, "应成功删除1条记录");

        // 验证删除结果
        Soul deletedSoul = soulMapper.selectById(soul.getSoulId());
        assertNull(deletedSoul, "删除后查询应返回null");
    }

    @Test
    void testQuerySoulDetails() {
        // 插入详细数据
        Soul soul = createTestSoul();
        soul.setDeathCause("Detailed Test Case");
        soul.setLifeSummary("This is a detailed life summary for testing.");
        soulMapper.insert(soul);

        // 执行查询
        Soul dbSoul = soulMapper.selectById(soul.getSoulId());

        // 验证详细字段
        assertAll("详细字段验证",
                () -> assertEquals("Detailed Test Case", dbSoul.getDeathCause()),
                () -> assertTrue(dbSoul.getLifeSummary().contains("detailed life summary")),
                () -> assertNotNull(dbSoul.getCreatedAt(), "创建时间应自动生成")
        );
    }

    @Test
    void testUniqueIdCardHashConstraint() {
        // 准备重复数据
        String uniqueHash = UUID.randomUUID().toString();
        Soul soul1 = createTestSoul();
        soul1.setIdCardHash(uniqueHash);

        Soul soul2 = createTestSoul();
        soul2.setIdCardHash(uniqueHash); // 故意重复

        // 首次插入应成功
        int firstInsert = soulMapper.insert(soul1);
        assertEquals(1, firstInsert);

        // 第二次插入应失败（需要捕获异常）
        Exception exception = assertThrows(Exception.class, () -> {
            soulMapper.insert(soul2);
        });
        assertTrue(exception.getMessage().contains("Duplicate entry"), "应触发唯一约束异常");
    }

    @Test
    void testCountByStatus() {
        List<Map<String, Object>> resultList = soulMapper.countByStatus();
        assertNotNull(resultList);

        // 调试输出
        System.out.println("Result List Size: " + resultList.size());
        for (Map<String, Object> row : resultList) {
            System.out.println("Row Content: " + row);
            if (row == null) {
                System.out.println("发现空行");
                continue;
            }
            for (Map.Entry<String, Object> entry : row.entrySet()) {
                System.out.printf("Key: %s, Value Type: %s%n",
                        entry.getKey(),
                        entry.getValue().getClass().getName());
            }
        }

        assertEquals(4, resultList.size());
    }
}